home *** CD-ROM | disk | FTP | other *** search
-
- ******************************************************************************
- * *
- * HodgePodge: An example Apple IIGS Desktop application *
- * *
- * Written in 65816 Assembler by the Apple IIGS Tools Team *
- * Modified by Ben Koning for "Programmer's Introduction to the Apple IIGS" *
- * *
- * Copyright (c) 1986-87 by Apple Computer, Inc. *
- * *
- * ---------------------------------------------------------------------- *
- * *
- * ASM65816 Code file "WINDOW.ASM" -- Open/Close windows *
- * *
- ******************************************************************************
-
-
-
- ****************************************************************
- *
- * HideAllWindows
- *
- ****************************************************************
-
- HideAllWindows START
- using GlobalDATA
-
- stz VIndex ;index for list of what was vis.
-
- HideLoop PushLong #0 ;hide 'em all, looks neater
- _FrontWindow
- ldx VIndex
- pla
- sta VTable,x
- pla
- sta VTable+2,x
- cmp #0
- bne dohid
- lda Vtable,x
- bne dohid
- rts ;all vis. windows hidden now
-
- doHid pha
- lda Vtable,x
- pha
- _HideWindow
- Lda Vindex
- clc
- adc #4
- sta Vindex
- bra HideLoop
-
- END
-
-
-
- ****************************************************************
- *
- * DoOpenItem :
- *
- * 1) Make sure not too many windows open already -- may show dialog
- *
- * 2) Call AddToMenu to add its name into the "windows" menu list
- *
- *
- ****************************************************************
-
- DoOpenItem START
-
- using GlobalDATA
- using FontDATA
-
- lda Windex ;Check if too many windows open already
- cmp #LastWind ;... otherwise "window" menu overflows!
- bcc OkToOpen ;No, so go ahead and try to open one
- jsr ManyWindDialog ;Yes, so confront user with dialog box
- sec ;Set carry because it didn't happen
- Done rts
-
- OkToOpen jsr OpenWindow
- bcs Done ;if we didn't open, don't add it
- jmp AddToMenu ;Add it to the menu list and exit
-
- END
-
-
-
- ****************************************************************
- *
- * DoSaveitem :
- *
- *
- ****************************************************************
-
- DoSaveItem START
- using GlobalDATA
- using IOData
-
-
- pushlong #0 ;it's the front window we're saving
- _FrontWindow
- pla
- sta whichwindow
- plx
- stx whichwindow+2 ;get result for pushing in a sec.
-
- PUSHLONG #0 ;space for result
- PUSHLONG whichwindow
- _GetWrefCon ;refcon has handle to data
-
- pla
- plx
-
- jsr deref
-
- sta 0
- sta Refptr
- stx 2
- stx Refptr+2
-
- ldy #oFlag ;check if picture
- lda [0],y
- beq oktosav ;save only type 0 windows
- rts
-
- oktosav PUSHLONG #0 ;space for result
- PUSHLONG whichwindow
- _GetWTitle
-
- pla
- sta NamePtr
- plx
- stx NamePtr+2
-
- PushWord #20 ; x loc
- PushWord #20 ; y loc
- PushLong #Prompt2 ; prompt string pointer
- PushLong NamePtr ; File name
- Pushword #15 ; Max file name length
- PushLong #reply ; reply list result
- _SFPutFile
-
- lda r_good ; <> 0 means OK to load it
- bne Saveitoff
-
- rts
-
-
- Saveitoff anop
-
- _WaitCursor
-
- lda Refptr
- sta 0
- lda Refptr+2
- sta 2
-
- ldy #oHandle
- lda [0],y
- sta PicHandle
- iny
- iny
- lda [0],y
- sta PicHandle+2 ; this de-refd, is the data to write oute pichandle (we'll de-allocate)
-
- lda PicHandle
- ldx PicHandle+2
- jsr DeRef
- sta PicDestOUT
- stx PicDestOUT+2 ; now pointing to what we write
-
- lda #R_fullPN ; put pointer to name in i/o param block
- sta NamePtr
- lda #^R_FullPN
- sta NamePtr+2
-
-
- nopack Jsr SaveOne
- Bcs OuttaHere
-
- fixnm lda refptr ; now fix up name
- clc
- adc #oLength ; where the name will go
- sta 0 ; save in 0,2 also for later indirect
- sta refptr
- lda refptr+2
- adc #0
- sta 2
- sta refptr+2
-
- lda r_Fname
- and #$00FF
- tay
- sep #%00100000
- longa off
- cpynm lda r_Fname,y
- sta [0],y
- dey
- bpl cpynm
- rep #%00100000
- longa on
-
- pushlong refptr ;(it points to string now, remember?)
- pushlong whichwindow
- _SetWTitle
-
- lda #0 ; re-calc size
- pha
- pha
- PushWord #WindowsMenuId
- _CalcMenuSize
-
- OuttaHere lda PicHandle
- ldx PicHandle+2
- jsr Unlock
-
- _InitCursor
-
- rts
- refptr ds 4
- END
-
-
-
- ****************************************************************
- *
- * OpenWindow:
- *
- * 1) Call SFGETFILE to get name of file to display in window
- * (or the dialog to select font if Display Font call)
- *
- * 2) Gets memory for, and loads the picture/font data into memory
- *
- * 3) Allocates a new window
- * a) puts handle to MyWindowInfo in WrefCon
- * b) note that routine to draw picture contents is set to "PAINT"
- * c) note for font draw contents is "DISPFONTWINDOW"
- *
- * The definition of MyWindowInfo is contained in global data
- *
- * If the menu manager is being used to add itemlist items with the file
- * name, it will squeeze the \N etc. together (see AddToMenu). In any
- * case, the file name string for the window title can still be found
- * starting at this area+5
- *
- * returns: carry set - didn't open it (user cancelled SFGETFILE)
- * carry clear - window opened
- *
- ****************************************************************
- OpenWindow START
- using GlobalDATA
- using IOData
- using FontDATA
- using WindowData
-
- lda TaskData
- cmp #ShowFontID ; is it open for font window?
- bne AskUser
- jsr DoChooseFont
- bcs stp
- jmp DoTheOpen
- stp rts ;cancelled choose font
-
-
-
- ********
- *
- * call SFGETFILE to request the file name
- *
- ********
- AskUser lda #20
- pha ; x loc.
- lda #20
- pha ; y loc.
- PushLong #Prompt ; prompt string pointer
- PushLong #OpenFilter ; Do dimmed display of unloadables
- PushLong #0 ; list of types to include -- 0 for all
- PushLong #reply ; reply list result
- _SFGetFile
- lda r_good ; <>0 means OK to load it
- bne loaditup
- sec ; carry set return: didn't open
- HandleError rts
-
- *********
- *
- * Get space for the picture file
- *
- ********
-
- LoadItUp anop
-
- _WaitCursor
-
- PushLong #0 ; space
- PushLong #$8000 ; size
- PushWord MyID ; id
- PushWord #$0000 ; no restrictions
- PushLong #0 ; loc not important
- _NewHandle
-
- pla
- sta PicHandle
- plx
- stx PicHandle+2
-
- bcs HandleError ; if error occured from no handle
-
- jsr Deref ; derefence handle (in a,x)
-
- sta PicDestIN ; put pointer in i/o param block
- stx PicDestIN+2
-
- DoTheOpen PushLong #0 ; space
- PushLong #MyWinfoSize ; size
- PushWord MyID ; id
- PushWord #$C000 ; fixed and locked
- PushLong #0 ; loc not important
- _NewHandle
-
- pla
- sta refcon
- plx
- stx refcon+2
-
- bcs HandleError
-
- jsr deref ;de ref. for storing stuff into
-
- sta refptr
- sta 0
- stx refptr+2
- stx 2
-
- *********
- *
- * Start by assuming this will be a picture window (not a font window).
- * We set the address of the drawing routine to PAINT and set the flag
- * in MyWindowInfo record to 0 indicating picture.
- *
- *********
-
- lda #Paint ; first the address of the Paint
- sta DrawRtn ; routine
- lda #^Paint
- sta DrawRtn+2
- ldy #oFlag ; Now set the flag field
- lda #0
- sta [0],y
-
-
- ;------------------------------------------------------------
- ;
- ; Now we see if that silly assumption above was correct.
- ;
- lda TaskData ; look at the menu item that
- cmp #ShowFontID ; brought us here.
- bne setIO ; not the font one so go on
-
- lda #1 ; fix the flag field
- ora MonoFlag ; set bit 1 if monospaced font
- sta [0],y ; (y still set)
- lda DesiredFont ; put the chosen fontid where
- sta PicHandle ; we will later put it in
- lda DesiredFont+2 ; the MyWindowInfo record
- sta PicHandle+2
-
- lda #DispFontWindow ; finally, fix the pointer to the
- sta DrawRtn ; drawing routine
- lda #^DispFontWindow
- sta DrawRtn+2
- jmp DoMovNam
-
- SetIO lda #R_fullPN ; put pointer to name in i/o param block
- sta NamePtr
- lda #^R_FullPN
- sta NamePtr+2
-
- *********
- *
- * load picture in "NamePtr" into "PicDest"
- *
- *********
- * check for packed or unpacked file load
-
-
- jsr LoadOne ; load it
- bcc DoMovNam
-
- IOError anop ; There was an error loading the file
- PushLong RefCon ; so dispose of the memory that we
- _DisposeHandle ; allocated while trying to create
- PushLong PicHandle ; this window
- _DisposeHandle
- sec
- rts
-
-
- **********
- *
- * Move the files name into the param block
- *
- **********
-
- DoMovNam lda refptr ;use zero page for indirect stores
- sta 0
- lda refptr+2
- sta 2
-
- lda pichandle ;into the recfon area (refptr)
- ldy #oHandle
- sta [0],y
- iny
- iny
- lda pichandle+2
- sta [0],y
-
- ldy #oBlank ; Put blank in record at blank field
- lda #' ' ; (note this 16 bit store will over-
- sta [0],y ; write the length field but we don't
- ; ; care since we fix it below.
-
- lda refptr
- clc
- adc #oLength ; where the name will go
- sta windaddr
- sta 0 ; save in 0,2 also for later indirect
- lda refptr+2
- adc #0
- sta windaddr+2
- sta 2
-
- lda r_Fname
- and #$00FF
- cmp #MaxNameSize
- bmi NameLenOK
- lda #MaxNameSize
- sep #%00100000
- sta r_Fname
- rep #%00100000
- NameLenOK tay
- sep #%00100000
- longa off
- cpynm lda r_Fname,y
- sta [0],y
- dey
- bpl cpynm
- rep #%00100000
- longa on
-
- ldy #350 ;adjust max siz
- ldx #640 ;adjust pixel count
- stx DataWidth
- stx mcw
- sty IsizPos+6
-
- ;------------------------------------------------------------
- ;
- ; Set up the DataHeight based on the type of window it is.
- ;
- lda #200 ; assume picture and make 200 the max
- sta DataHeight ; height
- lda RefPtr ; now see what it really is
- sta 0
- lda RefPtr+2
- sta 2
-
- lda TaskData
- cmp #OpenWID
- beq IsPicture
-
- PushLong #0 ; save this on the stack
- _GetFontID
-
- ldy #oFontID+2 ; now install the font that will
- lda [0],y ; be used in the current port
- pha
- dey
- dey
- lda [0],y
- pha
- PushWord #0
- _InstallFont
-
- PushLong #FIRecord ; get the font info so can get
- _GetFontInfo ; ascent and descent.
-
- PushLong #0 ; space for result
- lda ascent ; now multiply sum of ascent &
- clc ; descent by num lines to draw
- adc Descent
- pha
- PushWord #NumLines+1
- _Multiply
- pla ; put result in DataHeight
- sta DataHeight
- pla ; strip off high word of nothing
-
- jsr FindMaxWidth
-
- PushWord #0 ; using saved fontid on stack
- _InstallFont ; re-install the orig font
-
- IsPicture anop
- *********
- *
- * offset upperleft corner for opening of window
- *
- *********
- ldx #0
- MovOff lda ISizPos,x
- clc
- adc Wyoffset
- sta SizPos,x
- lda ISizPos+2,x
- clc
- adc Wxoffset
- sta SizPos+2,x
- inx
- inx
- inx
- inx
- cpx #8
- bne MovOff
-
- lda WxOffSet ;adjust offsets
- clc
- adc #20
- sta WxOffset
- lda WyOffset
- clc
- adc #12
- cmp #120 ;if we get too low, start at top
- bne DoYset
- lda #12
- doYset sta WyOffset
-
-
-
- **********
- *
- * Now, Finally, create the new window
- *
- **********
-
- Finally PushLong #0 ; space for result
- pushlong #WindowParamBlock
- _NewWindow
-
- pla
- sta whichwindow
- pla
- sta whichwindow+2
-
- PushLong WhichWindow ; set port to new top window
- _SetPort
-
- lda PicHandle ; unlock handle
- ldx PicHandle+2
- jsr Unlock
-
-
- **********
- *
- * Force origin boundaries (see Manual definition of Window Mgr's SetOriginMask)
- *
- **********
-
- PushWord #$FFFE
- PushLong whichwindow
- _SetOriginMask
-
- _InitCursor
-
- clc ; carry clear return: we opened it
- rts
- end
-
- ****************************************************************
- *
- * WindowData
- *
- ****************************************************************
- WindowData data
- WindowParamBlock anop
- dc i2'WindowEnd-WindowParamBlock'
- dc i2'FTitle+FClose+FRScroll+FBScroll+FGrow+FZoom+FMove+FVis'
- windaddr dc i4'0' Ptr to title
- refcon dc i4'0' RefCon
- dc i2'0,0,0,0' Full Size (0= default)
- dc i4'0' Color Table Pointer
- dc i2'0' Vertical origin
- dc i2'0' Horizontal origin
- DataHeight dc i2'200' Data Area Height
- DataWidth dc i2'640' Data Area Width
- dc i2'200' Max Cont Height
- McW dc i2'640' Max Cont Width
- dc i2'4' Number of pixels to scroll vertically.
- dc i2'16' Number of pixels to scroll horizontally.
- dc i2'40' Number of pixels to page vertically.
- dc i2'160' Number of pixels to page horizontally.
- dc i4'0' Infomation bar text string.
- dc i2'0' Info bar height
- dc i4'0' DefProc.
- dc i4'0' Routine to draw info. bar.
- DrawRtn dc i4'Paint' Routine to draw content.
- SizPos dc i2'0,0,0,0' Size/pos of content
- dc i4'$FFFFFFFF' Plane to put window up in.
- dc i4'0' Address for window record (0 to allocate)
- WindowEnd anop
-
- Refptr ds 4 ;refcon pointer to 20 bytes
- ISizPos dc i'20,10,80,350' ;Size/pos of content
-
-
- FiRecord anop
- Ascent ds 2
- Descent ds 2
- Leading ds 2
- WidMax ds 2
-
- END
-
- ****************************************************************
- *
- * OpenFilter
- *
- * This routine is passed to SFGetFile to filter out the filetypes
- * that are loadable by us.
- *
- * On entry, the stack looks like this:
- *
- * | previous contents |
- * |------------------------------|
- * | space for result | word
- * |------------------------------|
- * | pointer to directory entry | long
- * |------------------------------|
- * | return address | 3 bytes
- * |------------------------------|
- * | | <- SP
- *
- ****************************************************************
-
- OpenFilter start
- using GlobalData
-
- phb ; save DBR (and even out RTL addr)
- phk ; set DBR back to this bank
- plb
- pla ; save the return address
- sta RtnAddr
- pla
- sta RtnAddr+2
-
- tdc ; save the ROM's ZP
- sta DPSave
- lda MyZP ; and swap in ours
- tcd
-
- pla ; now get the pointer to the
- sta 0 ; directory entry
- pla
- sta 2
-
- ldx #1 ; assume visible and dimmed
-
- ldy #$10 ; look at the filetype byte
- lda [0],y
- and #$00FF ; don't look at the entire word
-
- cmp #$C1
- bne NotPicFile ; pass on all others
- ldx #2 ; show it as a selectable entry
-
- NotPicFile txa
- sta 1,s ; pass it back on the stack
-
- lda DPSave ; point back to the old DP
- tcd
-
- lda RtnAddr+2 ; and put the return address back
- pha
- lda RtnAddr
- pha
- plb ; restore old DBR
-
- rtl
-
- DPSave ds 2
- RtnAddr ds 4
-
- end
-
- ****************************************************************
- *
- * FindMaxWidth - this routine finds out how wide the window
- * should be for the currently installed font.
- *
- ****************************************************************
-
- FindMaxWidth start
- using WindowData
- using FontData
- using GlobalData
-
- PushWord #0 ; save prev set mono/pro flag
- _GetFontFlags
-
- ldy #oFlag ; keep the result on the stack while
- lda [0],y ; we set it to what we want (as
- lsr a ; defined by its window type set up
- and #$0001 ; when we open this window)
- pha
- _SetFontFlags
-
- stz MaxSoFar
- lda #1
- sta LineCounter
- LineLoop anop
-
- PushWord #0 ; space for width result.
- phk ; Get a pointer to the current line.
- phk ; The upper word is the same as the
- pla ; program bank.
- and #$00FF
- pha
- lda LineCounter ; The lower word is stored in a table.
- asl a
- tax
- lda LineTable,x
- pha
- _StringWidth
-
- pla ; How does this line compare with the
- cmp MaxSoFar ; previous longest line?
- bcc LessThan
- sta MaxSoFar ; > or =, so save it as record holder.
-
- LessThan anop
- inc LineCounter ; bump current line
- lda LineCounter
- cmp #NumLines
- bcc LineLoop
-
- lda MaxSoFar ; Get the width of longest line.
- clc ; Add in room for left and right margins
- adc #10
- sta DataWidth
-
- _SetFontFlags ; restore old settings
-
- rts
- LineCounter ds 2
- MaxSoFar ds 2
- end
-
- ****************************************************************
- *
- * DoCloseItem
- *
- * Close a window, and dispose of extra data (in WrefCom)
- * and remove it from window list. If no windows, then dim "Window"
- * menu and disallow printing.
- *
- ****************************************************************
- DoCloseItem START
- using GlobalDATA
-
- pushlong #0 ;it's the front window we're adding in
- _FrontWindow
- pla
- sta whichwindow
- pla
- sta whichwindow+2 ; get result for pushing in a sec.
- ora WhichWindow ; was there one?
- bne ThereIsOne
- GotIt rts ; quit now
-
- ThereIsOne PushLong WhichWindow ; if it is a system window, this will
- _CloseNDAByWinPtr ; close it
- bcc GotIt ; no error so done
-
- ; Must be one of mine.
- dothecls PUSHLONG #0 ;space for result
- PUSHLONG whichwindow
- _GetWrefCon ;refcon has handle to data
-
- pla
- sta temp2Handle
- plx
- stx Temp2Handle ;the refcon to de-allocate
-
- jsr deref
- sta 0
- stx 2
-
- ldy #oHandle
- lda [0],y
- sta PicHandle
- iny
- iny
- lda [0],y
- sta PicHandle+2 ; the pichandle (we'll de-allocate)
-
- ldy #oFlag ; check if picture or font
- lda [0],y
- beq itsapic
- stz PicHandle ; flag so we don't dispose
- stz PicHandle+2
-
-
- ItsAPic jsr AdjWind ; goes and pulls window from WindowList
-
- clc ; position returned in a-reg.
- adc #300 ; start at 300
- sta IDdelete ; the MenuID to del-allocate
-
- lda windex ; if only one, we must be special
- cmp #1
- bne MoreThanOne
-
- pushlong #origitem ; We're now deleting the only window
- pushword #0 ; left.
- pushword #WindowsMenuID
- _InsertMItem ; add old "no windows" menu item.
-
- Pushword #$0080 ;Disable windows menu
- PushWord #WindowsMenuID
- _SetMenuFlag
-
- Lda #True
- Sta NeedToUpdate
-
- stz PrintAvail ; Disallow printing
-
- lda #20 ; reset start loc for window sizing
- sta WxOffset
- lda #12
- sta WyOffSet
-
-
- MoreThanOne lda IDdelete
- pha ;now delete this item from menus
- _DeleteMItem
- dec windex
-
- lda windex ;now, renumber list
- beq nomore ; none left, skip
-
- sta IdCounter ; counts how many
- lda #300 ; always the starting no.
- sta IDstart ; will be first
- sta IDNew ; and the new one
- back lda IdStart
- cmp IdDelete ; is it the one we deleted?
- bne DoIt ; nope, go re-set ID
- inc Idstart ; yes, skip over it
- bra back
- DoIt pushword IdNew
- pushword IdStart
- _SetMItemId ; reset
- inc IdStart
- inc IdNew
- dec IdCounter
- bne back
-
- NoMore lda #0 ; re-calc size
- pha
- pha
- PushWord #WindowsMenuID
- _CalcMenuSize
-
- Pushlong Temp2Handle ;get rid of refcon area
- _DisposeHandle
-
- lda PicHandle ;is it font
- bne dodisp
- lda PicHandle+2
- beq skipdisp
-
-
- DoDisp Pushlong PicHandle ;get rid of picture area
- _DisposeHandle
-
- SkipDisp PushLong WhichWindow ;get rid of window
- _CloseWindow
-
- skip rts
- ****************************
- *
- * AdjWind finds and deletes a window list item which matches
- * "WhichWindow" and returns in a-reg. where it's position was
- *
- * Note: it's optimized to find things near end of list
- * (if you'd prefer the other end, you'd need some different logic,
- * but here, generally, you'll open, look at it, and close it, so
- * this method seems best)
- *
- ****************************
- AdjWind lda Windex
- tay ;use this to count thru
- dec a
- asl a ; pt. before last for end (a-2)*4
- asl a
- sta IDCounter
- adjloop dey
- bmi AdjDone
- tya
- asl a
- asl a
- tax
- lda WindowList,x ;get the pointer (uniqueness exists)
- cmp WhichWindow
- bne adjloop
- lda WindowList+2,x
- cmp WhichWindow+2
- beq shoveChk
- bra Adjloop
-
- ShoveIt lda WindowList+4,x ;now shove things up
- sta WindowList,x
- lda WindowList+6,x
- sta WindowList+2,x
- inx
- inx
- inx
- inx
- ShoveChk cpx IdCounter
- bne shoveit
- AdjDone tya
- rts
-
- IdNew ds 2
- IdStart ds 2
- IdCounter ds 2
- IDdelete ds 2
-
- END
-
- ****************************************************************
- *
- * Paint
- *
- * This draws picture in the window when task master calls.
- *
- ****************************************************************
- Paint START
- using GlobalData
- **********
- *
- * get my own zero page
- *
- **********
-
-
- phb
- phk
- plb
-
- phd
- lda MyZP
- tcd
-
- **********
- *
- * get the correct window port (got here from within taskmaster)
- *
- **********
-
- pushlong #0
- _GetPort
- plx
- ply ;get result for pushing in a sec.
-
- PUSHLONG #0 ;space for result
- phy
- phx ; saved the port here
- _GetWrefCon ;refcon has handle to data
-
- pla
- sta Temphandle
- plx
- stx TempHandle+2
-
- jsr Deref ; de reference
- sta 0
- stx 2
-
- ldy #oHandle ; get handle to pic data
- lda [0],y
- sta picptr
- pha
- iny
- iny
- lda [0],y
- sta picptr+2
- tax
- pla
-
- jsl PaintIt
-
- lda TempHandle
- ldx TempHandle+2
- jsr Unlock
-
- pld
- plb
-
- rtl
-
- END
-
- ****************************************************************
- *
- * PaintIt
- *
- * The routine which actually does the painting when passed the
- * the handle to the picture in the a & x registers.
- *
- ****************************************************************
- PaintIt START
- using GlobalData
-
- phx ; save this on stack
- pha
-
- jsr deref ;deref. picture handle
- sta picptr
- stx picptr+2
-
- PushLong #SrcLocInfo
- PushLong #SrcRect
- Pshmor PushWord #0 ; x
- PushWord #0 ; y
- PushWord #0 ; copy
- _PPToPort
-
- pla
- plx
- jsr Unlock
-
- rtl
-
- END
-
- ****************************************************************
- *
- * DoGoAway -- not necessary because we handle it the same as
- * DoCloseItem.
- *
- ****************************************************************
-
-
-
- ****************************************************************
- *
- * DoWindow
- *
- * Selects and shows window in response to menu selection.
- *
- ****************************************************************
- DoWindow START
- using GlobalDATA
-
- PUSHLONG WHICHWINDOW ; select first so it only redraws
- _SelectWindow ; once
-
- PUSHLONG WHICHWINDOW
- _ShowWindow
-
- rts
-
- END
-